package com.magic.zhixin.service;

import com.magic.zhixin.entity.*;
import com.magic.zhixin.handler.DelayTask.DelayTaskClient;
import com.magic.zhixin.handler.DelayTask.DelayedTask;
import com.magic.zhixin.model.QuestionStatus;
import com.magic.zhixin.model.QuestionType;
import com.magic.zhixin.model.TransferType;
import com.magic.zhixin.repository.*;
import com.magic.zhixin.utils.StringUtils;
import com.magic.zhixin.utils.ValidUtil;
import com.magic.zhixin.weixin.WeixinPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class ZhiXinWenDaService {
    @Autowired
    private UserQuestionRepository userQuestionRepository;
    @Autowired
    private QuestionBankRepository questionBankRepository;
    @Autowired
    private QuestionRepository questionRepository;
    @Autowired
    private AnswerRepository answerRepository;
    @Autowired
    private UserQuestionDetailRepository userQuestionDetailRepository;
    @Autowired
    private UserQuestionAnswerRepository userQuestionAnswerRepository;
    @Autowired
    private UserQuestionAnswerDetailRepository userQuestionAnswerDetailRepository;
    @Autowired
    private WeixinPayUtil weixinPayUtil;
    @Autowired
    private DelayTaskClient delayTaskClient;
    @Autowired
    private RedisService redisService;
    @Autowired
    private WalletService walletService;

    @Transactional
    public Result<QuestionBank> addQuestionBank(String name,UserInfo userInfo) {
        QuestionBank questionBank = questionBankRepository.findByCreateUserIdAndName(userInfo.getId(), name);
        if(questionBank != null){
            return Result.FailedResult("题库已存在");
        }
        questionBank = new QuestionBank();
        questionBank.setName(name);
        questionBank.setCreateUserId(userInfo.getId());
        questionBankRepository.save(questionBank);

        redisService.delete("CustomQuestionBank");
        return Result.OkResult(questionBank);
    }

    @Transactional
    public Result<QuestionBank> addQuestion(String questionTitle, List<String> anwserStr, Long questionBankId,UserInfo userInfo) {
        if(ValidUtil.isEmpty(questionTitle,anwserStr,questionBankId)){
            return Result.FailedResult("参数不正确");
        }
        Question question = questionRepository.findByQuestionBankIdAndTitleAndCreateUserId(questionBankId, questionTitle, userInfo.getId());
        if(question != null){
            return Result.FailedResult("问题已经存在");
        }

        question = new Question();
        question.setTitle(questionTitle);
        question.setQuestionBankId(questionBankId);
        question.setCreateUserId(userInfo.getId());
        question = questionRepository.save(question);

        List<Answer> answers = new ArrayList<>();
        for(String a: anwserStr){
            if(!StringUtils.isEmpty(a)||!"".equals(a)){
            Answer answer = new Answer();
            answer.setContent(a);
            answer.setQuestionId(question.getId());
            answer.setCreateUserId(userInfo.getId());
            answers.add(answer);  }
        }

        answerRepository.saveAll(answers);

        redisService.delete("Question-" + questionBankId);
        return Result.OkResult(question);
    }

    public Result getRandomQuestion(Long questionBankId,String oldQuestionIds) {
        List<Question> questions = redisService.getQuestionByQuestionBankId(questionBankId);
        if(CollectionUtils.isEmpty(questions)){
            return Result.FailedResult("当前题库不存在问题");
        }
        if(!StringUtils.isBlank(oldQuestionIds) && oldQuestionIds.split(",").length == questions.size()){
            return Result.FailedResult("当前题库不存在其他问题,请添加后在尝试");
        }

        Question question = null;
        Random random = new Random();

        int i = 0;
        while (true){
            i = random.nextInt(questions.size());
            question = questions.get(i);
            if(StringUtils.isBlank(oldQuestionIds) || !Arrays.asList(oldQuestionIds.split(",")).contains(question.getId()+"")){
                break;
            }
        }
        return Result.OkResult(question);
    }

    public Result<QuestionBank> getQuestionBank(Integer type,UserInfo userInfo) {
        return Result.OkResult(redisService.getQuestionBank(type,userInfo.getId()));
    }

    @Transactional(rollbackFor = Exception.class)
    public Result addUserQuestion(Long questionBankId, Integer totalAmount, String questionIds, String rightIds, Integer questionType, BigDecimal totalBonus,BigDecimal fee, Integer rewardAmount, Integer rightAmount,UserInfo userInfo) throws Exception {
        Optional<QuestionBank> optional = questionBankRepository.findById(questionBankId);
        if(!optional.isPresent()){
            return Result.FailedResult("题库不存在");
        }
        QuestionBank questionBank = optional.get();

        UserQuestion userQuestion = new UserQuestion();
        userQuestion.setAvatar(userInfo.getAvatar());
        userQuestion.setNickName(userInfo.getNickname());
        userQuestion.setUserId(userInfo.getId());
        userQuestion.setQuestionBankId(questionBankId);
        userQuestion.setQuestionBankName(questionBank.getName());
        userQuestion.setQuestionAmount(totalAmount);
        userQuestion.setQuestionType(QuestionType.values()[questionType]);
        userQuestion.setQuestionStatus(QuestionStatus.SUCCESS);
        if(QuestionType.HONGBAO_QUESTUON.getType() == questionType){
            userQuestion.setRightAmount(rightAmount);
            userQuestion.setTotalBonus(totalBonus);
            userQuestion.setFee(fee);
            userQuestion.setRewardAmount(rewardAmount);
            userQuestion.setQuestionStatus(QuestionStatus.COMMIT);
            userQuestion.setQuestionProgress(0);
            userQuestion.setSn(weixinPayUtil.generateSn());
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_MONTH,1);
            userQuestion.setExpireTime(calendar.getTime());
        }
        userQuestion.setRightIds(rightIds);
        userQuestion = userQuestionRepository.save(userQuestion);

        List<UserQuestionDetail> userQuestionDetailList = new ArrayList<>();
        String[] questions = questionIds.split(",");
        String[] answers = rightIds.split(",");
        for (int i = 0; i < questions.length ;i++){
            UserQuestionDetail userQuestionDetail = new UserQuestionDetail();
            Question question = questionRepository.findByIdIs(Long.valueOf(questions[i]));
            Answer answer = answerRepository.findByIdIs(Long.valueOf(answers[i]));
            userQuestionDetail.setQuestionId(question.getId());
            userQuestionDetail.setQuestionName(question.getTitle());
            userQuestionDetail.setAnswerId(answer.getId());
            userQuestionDetail.setAnswerContent(answer.getContent());
            userQuestionDetail.setUserQuestionId(userQuestion.getId());
            userQuestionDetailList.add(userQuestionDetail);
        }
        userQuestionDetailRepository.saveAll(userQuestionDetailList);

        //如果是红包 发起支付
        Map<String, Object> res = new HashMap<>();
        if(userQuestion.getQuestionType().getType() == QuestionType.HONGBAO_QUESTUON.getType()){
            res = walletService.transfer(userInfo.getId(), userQuestion.getSn(), userQuestion.getTotalBonus().add(fee), TransferType.PAY_HONGBAO_QUESTION);
        }
        delayTaskClient.addDelayTask(new DelayedTask(1,userQuestion.getId().toString(),userQuestion.getExpireTime()));
        res.put("userQuestion",userQuestion);

        redisService.delete("UserQuestion-" + userInfo.getId());
        return Result.OkResult(res);
    }

    public Result<UserQuestion> getMyQuestion(UserInfo userInfo) {
        return Result.OkResult(redisService.getUserQuestion(userInfo.getId()));
    }

    public Result<UserQuestionAnswer> getMyAnswerRecord(UserInfo userInfo) {
        return Result.OkResult(userQuestionAnswerRepository.findByUserId(userInfo.getId()));
    }

    public Result<UserQuestion> addUserQuestionAnswer(Long userQuestionId,String questionIds, String answerIds,UserInfo userInfo) throws Exception {
        UserQuestion userQuestion = userQuestionRepository.findByIdIs(userQuestionId);
        if(userQuestion == null){
            return Result.FailedResult("该问题不存在");
        }
        UserQuestionAnswer uqa = userQuestionAnswerRepository.findByUserIdAndUserQuestionId(userInfo.getId(), userQuestionId);
        if(uqa != null){
            return Result.FailedResult("已经回答过的问题不可以在回答");
        }

        UserQuestionAnswer userQuestionAnswer = new UserQuestionAnswer();
        userQuestionAnswer.setUserId(userInfo.getId());
        userQuestionAnswer.setAvatar(userInfo.getAvatar());
        userQuestionAnswer.setNickName(userInfo.getNickname());
        userQuestionAnswer.setUserQuestionId(userQuestionId);
        userQuestionAnswer = userQuestionAnswerRepository.save(userQuestionAnswer);

        //
        String[] questions = questionIds.split(",");
        String[] answers = answerIds.split(",");
        String[] rightIds = userQuestion.getRightIds().split(",");
        List<UserQuestionAnswerDetail> userQuestionAnswerDetailList = new ArrayList<>();
        int right = 0;
        for (int i = 0;i < answers.length ; i++){
            UserQuestionAnswerDetail userQuestionAnswerDetail = new UserQuestionAnswerDetail();
            userQuestionAnswerDetail.setAnswerId(Long.valueOf(answers[i]));
            userQuestionAnswerDetail.setAnswerContent(answerRepository.findByIdIs(Long.valueOf(answers[i])).getContent());
            userQuestionAnswerDetail.setQuestionId(Long.valueOf(questions[i]));
            userQuestionAnswerDetail.setQuestionName(questionRepository.findByIdIs(Long.valueOf(questions[i])).getTitle());
            userQuestionAnswerDetail.setUserQuestionAnswerId(userQuestionAnswer.getUserId());
            if(answers[i].equals(rightIds[i])){
                ++right;
                userQuestionAnswerDetail.setFlag(true);
            } else {
                userQuestionAnswerDetail.setFlag(false);
            }
            userQuestionAnswerDetailList.add(userQuestionAnswerDetail);
        }
        userQuestionAnswerDetailRepository.saveAll(userQuestionAnswerDetailList);

        userQuestionAnswer.setRightRate((double)right/answers.length);
        userQuestionAnswerRepository.save(userQuestionAnswer);

        //
        userQuestion.setAnswerAmount(userQuestion.getAnswerAmount() + 1);
        if(userQuestion.getQuestionType().getType() == QuestionType.HONGBAO_QUESTUON.getType()
                && userQuestion.getPrizeAmount() < userQuestion.getRewardAmount()
                && right >= userQuestion.getRightAmount()
                && userQuestion.getQuestionProgress().intValue() == 1){
            BigDecimal prize = userQuestion.getTotalBonus().divide(new BigDecimal(userQuestion.getRewardAmount()), BigDecimal.ROUND_DOWN, 2);
            userQuestionAnswer.setPrize(prize);
            userQuestionAnswerRepository.save(userQuestionAnswer);
            userQuestion.setPrizeAmount(userQuestion.getPrizeAmount() + 1);
            if(userQuestion.getPrizeAmount() >= userQuestion.getRewardAmount()){
                userQuestion.setQuestionProgress(1);
            }
            //转账
            walletService.transfer(userInfo.getId(),userQuestion.getSn(),prize,TransferType.GET_HONGBAO_QUESTUON);
        }
        userQuestionRepository.save(userQuestion);
        return Result.OkResult(null);
    }

    public Result<UserQuestion> getUserQuestionDetail(Long userQuestionId) {
        UserQuestion userQuestion = userQuestionRepository.findByIdIs(userQuestionId);
        List<UserQuestionAnswer> userQuestionAnswers = userQuestionAnswerRepository.findByUserQuestionId(userQuestion.getId());
        Map res = new HashMap();
        res.put("userQuestion",userQuestion);
        res.put("userQuestionAnswers",userQuestionAnswers);
        return Result.OkResult(res);
    }

    public Result<UserQuestionAnswerDetail> getUserQuestionAnswerDetail(Long userQuestionAnswerId) {
        List<UserQuestionAnswerDetail> userQuestionAnswerDetails = userQuestionAnswerDetailRepository.findByUserQuestionAnswerId(userQuestionAnswerId);
        return Result.OkResult(userQuestionAnswerDetails);
    }

    public Result<UserQuestion> getRightAnswer(Long userQuestionId,UserInfo userInfo) {
        UserQuestion userQuestion = userQuestionRepository.findByIdIs(userQuestionId);
        if(userInfo.getId().longValue() != userQuestion.getUserId().longValue()){
            return Result.FailedResult("不是出题人不能查看");
        }
        return Result.OkResult(redisService.getUserQuestionDetail(userQuestionId));
    }

    public Result<UserQuestionAnswer> getAllUserQuestionAnswer(Long userQuestionAnswerId) {
        UserQuestionAnswer userQuestionAnswer = userQuestionAnswerRepository.findByIdIs(userQuestionAnswerId);
        Long userQuestionId = userQuestionAnswer.getUserQuestionId();
        List<UserQuestionAnswer> userQuestionAnswers = userQuestionAnswerRepository.findByUserQuestionId(userQuestionId);
        return Result.OkResult(userQuestionAnswers);
    }

    public Result getNextQuestion(Long questionBankId, Long questionId) {
        if (questionId == null) {
            questionId = 0l;
        }
        Question question = questionRepository.findTop1ByQuestionBankIdAndIdGreaterThan(questionBankId, questionId);
        if (question == null) {
            return Result.FailedResult("无数据");
        }
        Map res = new HashMap();
        res.put("question", question);
        res.put("answers", answerRepository.findByQuestionId(question.getId()));
        return Result.OkResult(res);
    }

    public Result<Copywriting> getCopywriting(Integer type) {
        List<Copywriting> copywritings = redisService.getCopywriting(type);
        if(CollectionUtils.isEmpty(copywritings)){
            return Result.FailedResult("当前分类不存在文案");
        }
        Random random = new Random();
        return Result.OkResult(copywritings.get(random.nextInt(copywritings.size())));
    }

    public Result<UserQuestionAnswer> getMyUserQuestionAnswer(UserInfo userInfo, Long userQuestionId) {
        return Result.OkResult(userQuestionAnswerRepository.findByUserIdAndUserQuestionId(userInfo.getId(),userQuestionId));
    }

    public Result<UserQuestionDetail> getQuestionList(Long userQuestionId) {
        List<UserQuestionDetail> userQuestionDetails = redisService.getUserQuestionDetail(userQuestionId);
        if(CollectionUtils.isEmpty(userQuestionDetails)){
            return Result.OkResult(null);
        }
        userQuestionDetails.forEach(userQuestionDetail -> {
            List<Answer> answers = answerRepository.findByQuestionId(userQuestionDetail.getQuestionId());
            userQuestionDetail.setAnswers(answers);
        });
        return Result.OkResult(userQuestionDetails);
    }
}
